package cn.itcast.b_processDefinition;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.apache.commons.io.FileUtils;
import org.junit.Test;

public class ProcessDefinitionTest {

	ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
	
	/**
	 * 流程定义（从classpath
	 */
	@Test
	public void deploymentProcessDefinition_classpath(){
		Deployment deployment = processEngine.getRepositoryService()//与流程定义和部署对象相关的Service
						.createDeployment()//创建一个部署对象
						.name("流程定义")//添加部署的名称
						.addClasspathResource("diagrams/helloworld.bpmn")//从classpath的资源中加载，一次只能加载一个文件
						.addClasspathResource("diagrams/helloworld.png")//从classpath的资源中加载，一次只能加载一个文件
						.deploy();//完成部署
		System.out.println("部署ID："+deployment.getId());//
		System.out.println("部署名称："+deployment.getName());//
	}
	
	/**
	 * 部署流程定义（从zip）
	 */
	@Test
	public void deploymentProcessDefinition_zip(){
		InputStream in=this.getClass().getClassLoader().getResourceAsStream("diagrams/helloworld.zip");
		ZipInputStream zipInputStream=new ZipInputStream(in);
		
		Deployment deployment = processEngine.getRepositoryService()
		.createDeployment()//创建一个部署对象
		.addZipInputStream(zipInputStream)//指定zip格式的输入流
		.deploy();
		
		System.out.println("部署ID："+deployment.getId());//
		System.out.println("部署名称："+deployment.getName());//
	}
	/**
	 * 查询流程定义
	 */
	@Test
	public void findProcessDefinition(){
		
		List<ProcessDefinition> list = processEngine.getRepositoryService()//与流程定义和部署相关的service
		.createProcessDefinitionQuery()//创建一个流程定义查询
		/**指定查询条件**/
		//.deploymentId(arg0)//使用部署对象id查询
		//.processDefinitionId(arg0)//使用部署对象id查询
		//.processDefinitionKey(arg0)//使用流程定义的key查询
		//.processDefinitionNameLike(arg0)//使用流程定义的名称模糊查询
		/**排序**/
		.orderByProcessDefinitionVersion().asc()//按照版本的升序排列
		//.orderByProcessDefinitionName().desc()//按照流程定义的名称降序排列
		/**返回结果集**/
		.list();//返回一个集合列表
		//.singleResult()//返回唯一结果集
		//.count()//返回数量
		//.listPage(arg0, arg1)//分页操作
		if(list.size()>0){
			for(ProcessDefinition pd:list){
				System.out.println("流程定义id: "+pd.getId());//=流程定义的key+版本+随机生成数
				System.out.println("流程定义名称: "+pd.getName());//
				System.out.println("流程定义的key: "+pd.getKey());//对应helloworld.bpmn中的id
				System.out.println("流程定义的版本: "+pd.getVersion());//当key值相同是版本升级
				System.out.println("流程定义pmbn文件: "+pd.getResourceName());
				System.out.println("流程定义png文件: "+pd.getDiagramResourceName());
				System.out.println("部署对象id: "+pd.getDeploymentId());
				
			}
		}
		
	}
	/**
	 * 删除流程定义
	 */
	@Test
	public void deleteProcessDefinition(){
		String deployId="1";
		
		processEngine.getRepositoryService()
			/*
			 * 不带级联的删除
			 * 		只能删除没有启动的流程,如果流程启动,就会抛出异常
			 */
		//.deleteDeployment(deployId);
			/*
			 * 级联删除
			 * 		不管流程是否启动,都可删除
			 */
		.deleteDeployment(deployId, true);
		System.out.println("删除成功");
		
	}
	/**
	 * 查看流程图
	 * 	将生成的图片保存到文件下
	 */
	@Test
	public void findProcessPng(){
		String deployId="501";
		String reourceName="";
		//获取图片资源名称,会得到.bpmn和.png
		List<String> list = processEngine.getRepositoryService()
					.getDeploymentResourceNames(deployId);
		if(list.size()>0){
			for(String name:list){
				if(name.indexOf(".png")>=0){
					reourceName=name;
				}
			}
		}
		
		
		//获取图片的输入流
		InputStream inputStream = processEngine.getRepositoryService()
					.getResourceAsStream(deployId, reourceName);
		//将图片生成到D盘
		File file=new File("E://"+reourceName);
		try {
			FileUtils.copyInputStreamToFile(inputStream, file);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	/**
	 * 附加功能:查询最新版本的流程
	 */
	@Test
	public void findBastNewProcessPng(){
		
		List<ProcessDefinition> list = processEngine.getRepositoryService()
					.createProcessDefinitionQuery()
					.orderByProcessDefinitionVersion().asc()
					.list();
		Map<String,ProcessDefinition> map=new LinkedHashMap<String, ProcessDefinition>();
		if(list.size()>0){
			for(ProcessDefinition pd:list){
				map.put(pd.getKey(), pd);
			}
		}
		
		List<ProcessDefinition> list2=new ArrayList<ProcessDefinition>(map.values());
		System.out.println(" aaaa"+list2);
	}
	/**
	 * 附加功能:删除相同key的所有版本的流程
	 */
	@Test
	public void deleteAllVersionProcessPng(){
		//流程定义的key
		String processkey="helloworld";
		//先使用流程定义的key查询,查出所有的的版本
		List<ProcessDefinition> list = processEngine.getRepositoryService()
						.createProcessDefinitionQuery()
						.processDefinitionKey(processkey)//使用流程定义key查询
						.list();
		
		if(list.size()>0){
			//遍历获取每一个流程定义的部署id
			for(ProcessDefinition pd:list){
				//部署id
				String deploymentId = pd.getDeploymentId();
				
				processEngine.getRepositoryService()
								.deleteDeployment(deploymentId, true);
			}
		}
		
		
						
		
	}
}
